package model 
{
	import controller.ConditionsChecker;
	import events.MovedObjectEvent;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	import statemachine.StateMachine;
	import states.*;
	/**
	 * ...
	 * @author vkozhaev
	 */
	public class MGameboard extends EventDispatcher
	{

		private var _spaceships:Vector.<MSpaceship>;
		private var _asteroids:Vector.<MAsteroid>;
		private var _serviceStation:MServiceStation;
		private var _asteroidStore:MAsteroidStore;
		private var _stateMachine:StateMachine;
		
		private var _timer:Timer;
		
		public function MGameboard() 
		{
			
			
			this._spaceships = new Vector.<MSpaceship>();
			this._asteroids = new Vector.<MAsteroid>();
			_serviceStation = new MServiceStation();
			_asteroidStore = new MAsteroidStore();
			initAsteroids();
			initSpaceships();
			initStateMachine();
			
			_timer = new Timer(SetParameters.TIMER_TICK);
			_timer.addEventListener(TimerEvent.TIMER, timerHanlderTick);
		}
		
		public function initAsteroids():void {
			var asteroid:MAsteroid;
			asteroid = new MAsteroid();
			
			asteroid.cellCoords = new Point(3, 5);
			_asteroids.push(asteroid)
			asteroid = new MAsteroid();
			asteroid.cellCoords = new Point(2, 4);
			_asteroids.push(asteroid)
			asteroid = new MAsteroid();
			asteroid.cellCoords = new Point(6, 8);
			_asteroids.push(asteroid);
			
			for each (var asteroid:MAsteroid in _asteroids) {
				asteroid.initCoords();
			}
			
			
		}
		
		public function initSpaceships():void {
			var spaceship:MSpaceship;
			spaceship = new MSpaceship();
			
			spaceship.cellCoords = new Point(6, 7);
			_spaceships.push(spaceship)
			spaceship = new MSpaceship();
			spaceship.cellCoords = new Point(8, 10);
			_spaceships.push(spaceship)
			spaceship = new MSpaceship();
			spaceship.cellCoords = new Point(2, 5);
			_spaceships.push(spaceship);
			
			for each (var spaceship:MSpaceship in _spaceships) {
				spaceship.initCoords();
			}
			
			
		}
		
		public function initStateMachine():void {
			_stateMachine = new StateMachine();
			_stateMachine.conditionsChecker = new ConditionsChecker(this);
			_stateMachine.statesFactory = new StatesFactory(this);
			
			_stateMachine.setTransition(FindResourceState.NAME, ConditionsChecker.IS_ENERGY_NULL, NullEnergyState.NAME);
			_stateMachine.setTransition(FindResourceState.NAME, ConditionsChecker.IS_ENERGY_LOW, GoToEnergyStationState.NAME);
			_stateMachine.setTransition(FindResourceState.NAME, ConditionsChecker.IS_ASTEROID_NEAR_SHIP, GetResourcesState.NAME);
			_stateMachine.setTransition(FindResourceState.NAME, ConditionsChecker.IS_ASTEROID_NOT_NEAR_SHIP, FindResourceState.NAME);
			_stateMachine.setTransition(GetResourcesState.NAME, ConditionsChecker.IS_CARGO_BAY_FULL, FindResourceState.NAME);
			_stateMachine.setTransition(GetResourcesState.NAME, ConditionsChecker.IS_CARGO_BAY_NOT_FULL, FindResourceState.NAME);
			
			_stateMachine.setTransition(GoToEnergyStationState.NAME, ConditionsChecker.IS_SPACESHIP_NEAR_SERVICE, ProcessServiceState.NAME);
			_stateMachine.setTransition(GoToEnergyStationState.NAME, ConditionsChecker.IS_SPACESHIP_NOT_NEAR_SERVICE, GoToEnergyStationState.NAME);
			_stateMachine.setTransition(ProcessServiceState.NAME, ConditionsChecker.UNCONDITION_JUMP, FindResourceState.NAME);
			
		}
		
		public function removeAsteroid(asteroid:MAsteroid):void {
			var num:int = this._asteroids.indexOf(asteroid);
			_asteroids.splice(num, 1);
			dispatchEvent(new MovedObjectEvent(asteroid,MovedObjectEvent.ASTEROID_HAVE_BIN_PROCESSED));
		}
		
		public function startTimer():void {
			_timer.start();
			
		}
		
		private function timerHanlderTick(e:TimerEvent):void {
			for each (var spaceship:MSpaceship in _spaceships) {
				
				_stateMachine.processState(spaceship);
			}
			dispatchEvent(e);			
		}
		
		
		public function get spaceships():Vector.<MSpaceship> {
			return _spaceships;
		}
		
		public function get asteroids():Vector.<MAsteroid> {
			return _asteroids;
		}
		
		public function get serviceStation():MServiceStation {
			return _serviceStation;
		}
		
		public function get asteroidStore():MAsteroidStore {
			return _asteroidStore;
		}
		
	}

}